package ge.gen.eBdgt.vo;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

@SuppressWarnings("serial")
public abstract class ValueObject implements Serializable, Cloneable {

    private static final List<String> commonFields;
    static {
        commonFields = new ArrayList<String>();
        commonFields.add("class");
        commonFields.add("modified");
        commonFields.add("crud");
        commonFields.add("numfields");
    }

    public static final String NOT_A_COLUMN = "";
    protected byte[] dirtyAttrs;
    protected String[] originalValue;
    protected boolean existingRow = false;
    protected String var;
    

    protected CRUD crud = CRUD.READ;

    public void setCRUD(final CRUD crud) {
        this.crud = crud;
    }

    public CRUD getCRUD() {
        return this.crud;
    }

    public final boolean isModified(final int indexNo) {
        return (this.dirtyAttrs[indexNo] > 0);
    }

    public abstract int getNumFields();

    public abstract int getFieldIndex(final String fieldName);

    public abstract String getColumnName(final int indexNo);

    public abstract String getTableName(final int indexNo);

    public abstract Object getFieldValue(final int indexNo);

    public Object getFieldValue(final String fieldName) {
        return getFieldValue(getFieldIndex(fieldName));
    }

    public final boolean isModified() {
        boolean isModified = false;
        if (isExistingRow()) {
            for (int i = 0; i < getNumFields(); i++) {
                if (this.dirtyAttrs[i] > 0) {
                    isModified = true;
                }
            }
        }
        return isModified;
    }

    public final void resetIsModified() {
        for (int indexNo = 0; indexNo < this.dirtyAttrs.length; indexNo++) {
            if (this.dirtyAttrs[indexNo] != -1) {
                this.dirtyAttrs[indexNo] = 0;
            }
        }
    }

    public final void resetIsModified(final int indexNo) {
        if (this.dirtyAttrs[indexNo] != -1) {
            this.dirtyAttrs[indexNo] = 0;
        }
    }

    public final void resetOriginalValues() {
        originalValue = null;
        for (int indexNo = 0; indexNo < getNumFields(); indexNo++) {
            if (dirtyAttrs[indexNo] == 0) {
                saveOriginalValue(indexNo, getFieldValue(indexNo));
            }
        }
    }

    public final void resetVOtoClean() {
        this.setCRUD(CRUD.READ);
        resetIsModified();
        resetOriginalValues();
    }

    protected final void saveOriginalValue(final int indexNo, final Object value) {
        if (originalValue == null) {
            originalValue = new String[getNumFields()];
        }
        if (originalValue[indexNo] == null) {
            originalValue[indexNo] = String.valueOf(value);
        }
    }

    public final void setOriginalValue(final int indexNo, final Object value) {
        if (originalValue == null) {
            originalValue = new String[getNumFields()];
        }
        originalValue[indexNo] = String.valueOf(value);
    }

    public final String getOriginalValue(final int indexNo) {
        String origVal = null;
        if (originalValue == null) {
            originalValue = new String[getNumFields()];
        } else {
            origVal = originalValue[indexNo];
        }
        if (origVal == null) {
            origVal = "";
        }
        return origVal;
    }

    public boolean isCommonField(final String fieldName) {
        return commonFields.contains(fieldName.toLowerCase());
    }

    public String getVar() {
        return var;
    }

    public void setVar(final String var) {
        this.var = var;
    }

    public boolean isExistingRow() {
        return existingRow;
    }

    public void setExistingRow(final boolean existingRow) {
        this.existingRow = existingRow;
    }

   
}
